#include <user/ulib.h>

struct pipe_t *rpc_in_pipe, *rpc_out_pipe;

int
rpc_init(void)
{
	 rpc_in_pipe = pipe_new();
	 rpc_out_pipe = pipe_new();
	 
	 return 0;
}

int
rpc_send(uint16_t pidx, uint32_t func)
{
	 /* 等待消息队列空闲 */
	 waitb(ENV_SCH_IEC_SEND_BLOCKING);

	 uint32_t in_handler;
	 uint32_t out_handler;

	 /* 获取 pipe 的句柄 */
	 if ((in_handler = pipe_share(rpc_in_pipe)) == 0)
		  return -E_INVAL;
	 if ((out_handler = pipe_share(rpc_out_pipe)) == 0)
		  return -E_INVAL;

	 
	 iec_send(pidx, RPC_HEADER, func, in_handler, out_handler);
}

void
rpc_wait(void)
{
	 /* 等待消息队列空闲 */
	 waitb(ENV_SCH_IEC_SEND_BLOCKING);
}

int
rpc_recv(uint16_t *pidx, uint32_t *func, struct pipe_t **in_pipe, struct pipe_t **out_pipe)
{	 
	 int idx;
	 uint32_t in_handler, out_handler;

	 while (1)
	 {
		  /* 等待消息 */
		  waitb(ENV_SCH_IEC_RECV_BLOCKING);

		  *pidx = envs[self_idx].iec.recv.begin;

		  /* 检查是否是 RPC CALL 请求 */
		  if (envs[*pidx].iec.cache.arg_a != RPC_HEADER)
			   continue;
		  
		  
		  *func = envs[*pidx].iec.cache.arg_b;
		  in_handler = envs[*pidx].iec.cache.arg_c;
		  out_handler = envs[*pidx].iec.cache.arg_d;

		  /* 接受数据, 开启共享 pipe */
		  if ((*in_pipe = pipe_open(in_handler)) == NULL)
		  {
			   /* 资源不够 */
			   iec_recv(*pidx);

			   return -E_NO_MEM;
		  }
		  else if ((*out_pipe = pipe_open(out_handler)) == NULL)
		  {
			   pipe_close(*in_pipe);
			   /* 资源不够 */
			   iec_recv(*pidx);

			   return -E_NO_MEM;
		  }

		  break;
	 }
}

void
rpc_return(uint16_t pidx, struct pipe_t *in_pipe, struct pipe_t *out_pipe)
{
	 pipe_close(in_pipe);
	 pipe_close(out_pipe);
	 iec_recv(pidx);
}

